﻿using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.CodeCompletion;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using ICSharpCode.AvalonEdit.Search;
using Magic.Actions;
using Magic.Models.Controls;
using Magic.Tools.AvalonEditer;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml;

namespace Magic.Tools.Models.Tables
{
    public class CodeEditorTableItem : CostomTabItem
    {

        #region Private Property
        protected TextEditor textEditor { get; private set; }
        private CompletionWindow completionWindow { get; set; }
        #endregion

        public CodeEditorTableItem()
        {

        }


        protected override void OnClosed(object param)
        {
            base.OnClosed(param);
        }

        protected override void OnSelected()
        {
            this.textEditor.TextArea.Focus();
        }

        protected override void OnContentChanged()
        {
            if (this.Content != null)
            {
                this.textEditor = this.Content.FindChild<TextEditor>();
                if (this.textEditor != null)
                {
                    // Load our custom highlighting definition
                    IHighlightingDefinition customHighlighting;

                    using (var file = File.Open(@"Themes\Editor\TextEditor.xshd", FileMode.Open))
                    {
                        using (XmlReader reader = new XmlTextReader(file))
                        {
                            customHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
                            // and register it in the HighlightingManager
                            HighlightingManager.Instance.RegisterHighlighting("TextEditor", new string[] { ".xal" }, customHighlighting);
                        }
                    }

                    this.textEditor.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
                    this.textEditor.SetValue(TextOptions.TextRenderingModeProperty, TextRenderingMode.ClearType);
                    textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("TextEditor");
                    //textEditor.SyntaxHighlighting = customHighlighting;
                    //TextEditor.xshd
                    this.OriginFontSize = this.textEditor.FontSize;
                    this.textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering;
                    this.textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered;
                    this.textEditor.TextArea.MouseWheel += TextEditor_MouseWheel;
                    this.textEditor.TextArea.Document.TextChanged += Document_TextChanged;
                    this.textEditor.MouseHover += TextEditor_MouseHover;
                    this.textEditor.MouseHoverStopped += TextEditor_MouseHoverStopped;
                    SearchPanel.Install(this.textEditor);
                    Console.WriteLine(customHighlighting.MainRuleSet);
                    this.textEditor.Document.Text = @"using Magic.Controls;

namespace Magic.Tools.Controls
{
    /// <summary>
    /// CodeEditerPage.xaml 的交互逻辑
    /// </summary>
    public partial class CodeEditorPage : DesignerPage
    {
        public CodeEditorPage()
        {
            InitializeComponent();
		}

        private void TextEditor_ToolTipOpening(object sender, System.Windows.Controls.ToolTipEventArgs e)
        {

        }
    }
}
";
                }
            }
        }

        private void TextEditor_MouseHoverStopped(object sender, System.Windows.Input.MouseEventArgs e)
        {
            toolTip.IsOpen = false;
        }

        private void TextEditor_MouseHover(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var pos = textEditor.GetPositionFromPoint(e.GetPosition(textEditor));

            if (pos.HasValue)
            {

                var lineText = textEditor.Document.GetLineByNumber(pos.Value.Line);
                var text = textEditor.Document.GetText(lineText.Offset + pos.Value.Column - 1, 1);




                if (!String.IsNullOrWhiteSpace(text))
                {
                    toolTip.PlacementTarget = textEditor; //属性继承所需的
                    toolTip.Content = text;
                    toolTip.IsOpen = true;
                    e.Handled = true;
                }





            }

        }

        ToolTip toolTip = new ToolTip();



        private void Document_TextChanged(object sender, EventArgs e)
        {
            this.IsChanged = true;
        }

        private void TextEditor_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if ((Keyboard.Modifiers & ModifierKeys.Control) != ModifierKeys.None)
            {
                if (e.Delta > 0)
                {
                    ZoomValue += 0.1;
                }
                else
                {
                    if (ZoomValue >= 0.2)
                    {
                        ZoomValue -= 0.1;
                    }

                }
            }



        }

        protected override void ZoomValue_Changed()
        {
            this.textEditor.FontSize = this.ZoomValue * OriginFontSize;
        }


        #region MyRegion



        void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
        {
            switch (e.Text)
            {
                case "{":
                    textEditor.Document.Insert(textEditor.TextArea.Caret.Offset, "}");
                    textEditor.TextArea.Caret.Offset -= 1;
                    break;
                case "(":
                    textEditor.Document.Insert(textEditor.TextArea.Caret.Offset, ")");
                    break;
                case "[":
                    textEditor.Document.Insert(textEditor.TextArea.Caret.Offset, "]");
                    break;
                case "\"":
                    textEditor.Document.Insert(textEditor.TextArea.Caret.Offset, "\"");
                    textEditor.TextArea.Caret.Offset -= 1;
                    break;
                case "\'":
                    textEditor.Document.Insert(textEditor.TextArea.Caret.Offset, "\'");
                    textEditor.TextArea.Caret.Offset -= 1;
                    break;
            }

            if (e.Text == ".")
            {
                var position = textEditor.TextArea.Caret.Offset - 1;
                while (position > 0)
                {
                    var text = textEditor.Document.GetText(position, 1);
                    if (text == " ")
                    {
                        text = textEditor.Document.GetText(position, textEditor.TextArea.Caret.Offset - position - 1);
                        break;
                    }
                    position--;
                }

                Console.WriteLine(e.ControlText);
                // open code completion after the user has pressed dot:
                completionWindow = new CompletionWindow(textEditor.TextArea);
                completionWindow.ResizeMode = ResizeMode.NoResize;
                // provide AvalonEdit with the data:
                IList<ICompletionData> data = completionWindow.CompletionList.CompletionData;
                data.Add(new MethodCompletionData("Add"));
                data.Add(new MethodCompletionData("Remove"));
                data.Add(new PropertyCompletionData("Count"));
                data.Add(new PropertyCompletionData("Length"));
                data.Add(new MethodCompletionData("Copy"));
                data.Add(new PropertyCompletionData("TaskCount"));
                data.Add(new MethodCompletionData("CreateFile"));
                data.Add(new PropertyCompletionData("Time"));

                data.Add(new MethodCompletionData("SetLeft"));
                data.Add(new MethodCompletionData("GetLeft"));
                data.Add(new PropertyCompletionData("Left"));

                data.Add(new MethodCompletionData("SetTop"));
                data.Add(new MethodCompletionData("GetTop"));
                data.Add(new PropertyCompletionData("Top"));

                data.Add(new MethodCompletionData("SetWidth"));
                data.Add(new MethodCompletionData("GetWidth"));
                data.Add(new PropertyCompletionData("Width"));

                data.Add(new MethodCompletionData("SetHeight"));
                data.Add(new MethodCompletionData("GetHeight"));
                data.Add(new PropertyCompletionData("Height"));


                completionWindow.CompletionList.SelectedItem = data[0];
                completionWindow.MaxHeight = 450;
                completionWindow.Show();
                completionWindow.Closed += delegate
                {
                    completionWindow = null;
                };
            }
        }

        void textEditor_TextArea_TextEntering(object sender, TextCompositionEventArgs e)
        {
            if (e.Text.Length > 0 && completionWindow != null)
            {
                if (!char.IsLetterOrDigit(e.Text[0]))
                {
                    // Whenever a non-letter is typed while the completion window is open,
                    // insert the currently selected element.
                    completionWindow.CompletionList.RequestInsertion(e);
                }
            }
            // do not set e.Handled=true - we still want to insert the character that was typed
        }
        #endregion



        public void SetEditorFontSize(Double size)
        {
            OriginFontSize = size;
            ZoomValue_Changed();
        }



        private Double OriginFontSize { get; set; }

    }

}
